package controllers

import (
	"blog/bootstrap/driver"
	"blog/modules"
	"blog/utils"
	"fmt"
	"log"
	"net/http"
	"strconv"

	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
)

func RLogin(c *gin.Context) {
	auth := Auth{}.GetAuth(c)
	if auth.Id != 0 {
		utils.Redirect(c, "/")
	}
	data := struct {
		Auth
	}{auth}
	c.HTML(http.StatusOK, "root_login", data)
}

func RootDoLogin(c *gin.Context) {
	var logData struct {
		Email    string `form:"email" json:"email" binding:"required" `
		Password string `form:"password" json:"password" binding:"required"`
	}
	// 验证数据
	if err := c.ShouldBind(&logData); err != nil { //将请求的数据绑定到logData结构体上，若err != nil则返回失败的响应
		response := utils.Response{
			Status: 403,
			Data:   nil,
			Msg:    err.Error(),
		}
		c.JSON(http.StatusOK, response.FailedResponse())
		return
	}
	// 查找数据库中的用户
	user := modules.Root{}
	err := driver.Db.Where("email = ?", logData.Email).First(&user).Error
	if err != nil || len(user.Email) <= 0 {
		msg := "登录失败， 请确认邮箱是否正确!"
		js := fmt.Sprintf("<script>alert('%s');history.back();</script>", msg)
		c.Writer.WriteString(js)
		return
	}

	// 找到后验证密码是否匹配
	ok := utils.VerifyRootPassword(&user, logData.Password)
	if !ok {
		msg := "邮箱或者密码错误."
		js := fmt.Sprintf("<script>alert('%s');history.back();</script>", msg)
		c.Writer.WriteString(js)
		return
	}

	// 验证成功后， 写将用户的信息写入session中
	auth := &Auth{
		Id:         int(user.ID),
		Name:       user.Name,
		Avatar:     user.Avatar,
		Profession: user.Profession,
	}

	sess := sessions.Default(c) //获取会话对象
	sess.Set("auth", auth)      //设置session值
	err = sess.Save()           //保存会话数据
	if err != nil {
		panic(err)
	}
	fmt.Println("success=>")
	utils.Redirect(c, "/")
}

// method : GET
// 更新密码
func RootUpdatePwd(c *gin.Context) {
	auth := Auth{}.GetAuth(c) //获取session中的用户信息
	data := struct {
		Auth
		Title string
	}{
		auth,
		"修改密码",
	}
	c.HTML(http.StatusOK, "root_update_pwd", data)
}

// 修改密码 POST
func RootDoUpdatePwd(c *gin.Context) {
	auth := Auth{}.GetAuth(c)
	password := c.PostForm("pwd")
	re_password := c.PostForm("re_pwd")
	if password != re_password {
		msg := "密码不一致"
		js := fmt.Sprintf("<script>alert('%s');history.back();</script>", msg)
		c.Writer.WriteString(js)
		return
	}
	salt := utils.Salt()
	user, err := modules.GetRootByID(auth.Id)
	if err != nil {
		log.Println(err)
	}
	user.Salt = salt
	user.Password = utils.CryptUserPassword(password, salt)
	err = user.Update() //加密后重新更新用户的密码
	if err != nil {
		msg := "更新失败，请联系管理员"
		js := fmt.Sprintf("<script>alert('%s');history.back();</script>", msg)
		c.Writer.WriteString(js)
		return
	}
	fmt.Println("success")
	utils.Redirect(c, "/")
}

// UserManage 用户个人信息
func UserManage(c *gin.Context) {
	auth := Auth{}.GetAuth(c)
	var users []modules.User

	dbQuery := driver.Db.Table("users").Order("created_at desc") //获取用户信息
	paginate, err := (&modules.Pagination{}).Paginate(c, *dbQuery, &users)
	if err != nil {
		panic(err)
	}
	fmt.Println("paginate=>", paginate.Data)
	data := struct {
		Paginate modules.Pagination
		Auth
	}{
		*paginate, auth,
	}
	c.HTML(http.StatusOK, "user_list", data)
}

// DelUser 删除用户
func DelUser(c *gin.Context) {
	id := c.Param("id")
	fmt.Println("id=====>", id)
	err := driver.Db.Table("users").Where("id = ?", id).Delete(nil).Error
	if err != nil {
		fmt.Println("Delete Error :", err)
	} else {
		fmt.Println("delete success")
		UserManage(c)
	}
}

func ResetPwd(c *gin.Context) {
	id := c.Param("id")
	password := "123456"
	newId, _ := strconv.Atoi(id)
	salt := utils.Salt()
	user, err := modules.GetUserByID(newId)
	if err != nil {
		log.Println(err)
	}
	user.Salt = salt
	user.Password = utils.CryptUserPassword(password, salt)
	err = user.Update() //加密后重新更新用户的密码
	if err != nil {
		msg := "重置失败，请联系管理员"
		js := fmt.Sprintf("<script>alert('%s');history.back();</script>", msg)
		c.Writer.WriteString(js)
		return
	} else {
		UserManage(c)
	}
}

func UserSearch(c *gin.Context) {
	auth := Auth{}.GetAuth(c)
	name := c.PostForm("userName")
	var users []modules.User

	dbQuery := driver.Db.Table("users").Where("name LIKE ?", "%"+name+"%").Order("created_at desc") //获取用户信息
	paginate, err := (&modules.Pagination{}).Paginate(c, *dbQuery, &users)
	if err != nil {
		panic(err)
	}
	data := struct {
		Paginate modules.Pagination
		Auth
	}{
		*paginate, auth,
	}
	c.HTML(http.StatusOK, "user_list", data)
}

func ArticleManage(c *gin.Context) {
	auth := Auth{}.GetAuth(c)
	var articles []modules.Article
	dbQuery := driver.Db.Table("articles").
		Joins("JOIN users ON articles.user_id = users.id").
		Order("articles.updated_at desc").Preload("User")
	paginate, err := (&modules.Pagination{}).Paginate(c, *dbQuery, &articles)
	if err != nil {
		panic(err)
	}
	data := struct {
		Paginate modules.Pagination
		Auth
	}{
		*paginate, auth,
	}
	c.HTML(http.StatusOK, "article_list", data)
}

func ArticleDel(c *gin.Context) {
	id := c.Param("id")
	err := driver.Db.Table("articles").Where("id = ?", id).Delete(nil).Error
	if err != nil {
		fmt.Println("Delete Error :", err)
	} else {
		fmt.Println("delete success")
		ArticleManage(c)
	}
}

func ArticleSearch(c *gin.Context) {
	auth := Auth{}.GetAuth(c)
	title := c.PostForm("title")
	var articles []modules.Article

	dbQuery := driver.Db.Table("articles").Where("title LIKE ?", "%"+title+"%").Joins("JOIN users ON articles.user_id = users.id").
		Order("articles.updated_at desc").Preload("User") //获取用户信息
	paginate, err := (&modules.Pagination{}).Paginate(c, *dbQuery, &articles)
	if err != nil {
		panic(err)
	}
	data := struct {
		Paginate modules.Pagination
		Auth
	}{
		*paginate, auth,
	}
	c.HTML(http.StatusOK, "article_list", data)
}
